package com.zhss.security.demospringsecurity.config.filter;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName JsonLoginFilter
 * @Description TODO
 * @Author leejiliang
 * @DateTime 2021/9/14 14:50
 * @Version 1.0
 */
public class JsonLoginFilter extends UsernamePasswordAuthenticationFilter {

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
		if (!request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException(
					"Authentication method not supported: " + request.getMethod());
		}

		if (request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) ||
				request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE)) {
			Map<String, String> userInfo;
			try {
				final ObjectMapper objectMapper = new ObjectMapper();
				userInfo= objectMapper.readValue(request.getInputStream(), Map.class);
				final String username = userInfo.get(getUsernameParameter());
				final String password = userInfo.get(getPasswordParameter());
				final UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
				setDetails(request, token);
				return this.getAuthenticationManager().authenticate(token);

			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return super.attemptAuthentication(request, response);
	}
}
